// Copyright (C) 2010 Razvan Constantin <razvan.constantin@rconst.net>
//
// This file is part of FileBow.
//
// FileBow is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// FileBow is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with FileBow.  If not, see <http://www.gnu.org/licenses/>.

#ifndef FILEBOW_LOGIC_PATH_SCANNER_H__
#define FILEBOW_LOGIC_PATH_SCANNER_H__

#include <memory>
#include <string>
#include <vector>

#include <Poco/Path.h>

#include "common/common.h"

namespace filebow {
class PathTree;

/**
 * Recusively scans a directory and stores results in a PathTree.
 */
class PathScanner {

  /**
   * Constructor
   * @param initPath The path to scan.
   */
  public: PathScanner(const Poco::Path& path);

  /** Destructor */
  public: virtual ~PathScanner();

  /**
   * Sets the maximum depth for recursive scanning.
   * A negative value (-1 by convention, default) removes any limitation.
   * 0 indicates no recursion.
   */
  public: void SetMaxDepth(int depth) { mMaxDepth = depth; }

  /**
   * Sets the maximum number of files to scan from a folder.
   * A ngative value (-1 by convention, default) removes any limitation.
   * Cannot be 0.
   */
  public: void SetMaxFiles(int limit) { mMaxFiles = limit; }

  /**
   * Sets patterns to be excluded during scan.
   * @param patterns Exclusion patterns.
   */
  public: void SetExclusionPatterns(const std::vector<std::string>& patterns);

  /**
   * Tree access with corresponding lock mechanism.
   */
  public: PathTree* tree() const { return mTree.get(); }
  public: void Lock();
  public: void Unlock();

  /**
   * Performs the actual scan and stores the results in tree.
   */
  public: virtual void Scan(PathTree* tree);
  public: virtual void AsyncScan();
  public: virtual void Wait();

  /**
   * Does asynchronous scanning
   */
  private: void InternalScan();

  /** Indicates wheather given count is over maximum files to scan. */
  private: bool OverMaxFiles(int count) const;

  /** Indicates whether given depth is over maximum depth to scan. */
  private: bool OverMaxDepth(int depth) const;

  /** pimpl. */
  class Impl;
  private: std::auto_ptr<Impl> pimpl;

  /** Path to scan. */
  private: Poco::Path mPath;

  /** Max depth for recursion. */
  private: int mMaxDepth;

  /** Max number of files to scan in path. */
  private: int mMaxFiles;

  /** Tree associated to the scanned path. */
  private: std::auto_ptr<PathTree> mTree;

  /** Exclusion patterns. */
  private: std::vector<std::string> mExcludes;

  DISALLOW_COPY(PathScanner);
};

} // namespace filebow

#endif // FILEBOW_LOGIC_PATH_SCANNER_H__
